package 代码题.生产者消费者题目;

/**
 * 使用synchronized实现生产者消费者模式
 * 使用synchronized+wait+notify的组合
 *
 * 打印消息的速度不一定比notify快。
 */
public class SynchronizedStrategy {

    public static void main(String[] args){
        SyncQueue selfqueue = new SyncQueue();
        Thread prodThread = new Thread(new SyncProducer(selfqueue));
        Thread consThread = new Thread(new SyncConsumer(selfqueue));
        prodThread.start();
        consThread.start();
    }
}

class SyncQueue{
    int index = 0;
    int[] ProdLine = new int[6];

    //锁this对象，两个方法不可能同时执行
    public synchronized void produce(int ProdRandom){
        while(index == ProdLine.length){
            try {
                System.out.println("队列已满");
                this.wait(); //释放了锁,挂起线程，退出方法，当被唤醒时，继续从这里执行
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("生产的数据: " + ProdRandom);
        ProdLine[index] = ProdRandom;
        index++;
        this.notify();  //唤醒消费者,但是没有获取到锁
    }

    //syncchronized方法结束，自动释放锁
    public synchronized void consume(){
        while(index == 0){
            try {
                System.out.println("队列为空");
                this.wait(); //释放了锁。挂起线程，退出方法
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        index--;
        int m=ProdLine[index];
        System.out.println("消费的数据: "+m);
        this.notify();  //唤醒生产者，但是没有获取到锁，只是处于就绪状态
    }
}

//生产者
class SyncProducer implements Runnable{
    private final SyncQueue selfqueue;
    public SyncProducer(SyncQueue selfqueue) {
        this.selfqueue = selfqueue;
    }
    public void run() {
        for (int i = 0; i < 10; i++) {
            selfqueue.produce(i);
        }
    }
}

//消费者
class SyncConsumer implements Runnable{
    private final SyncQueue selfqueue;
    public SyncConsumer(SyncQueue selfqueue) {
        this.selfqueue = selfqueue;
    }
    public void run() {
        while(true) {
            selfqueue.consume();
        }
    }
}
